Completed
Push — master ( 03e877...7bde6b )
by Maxence
02:49 queued 11s
created

curr.getProviderResult   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 2
nc 2
nop 1
1
/*
2
 * FullTextSearch - Full text search framework for Nextcloud
3
 *
4
 * This file is licensed under the Affero General Public License version 3 or
5
 * later. See the COPYING file.
6
 *
7
 * @author Maxence Lange <[email protected]>
8
 * @copyright 2018
9
 * @license GNU AGPL version 3 or any later version
10
 *
11
 * This program is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License as
13
 * published by the Free Software Foundation, either version 3 of the
14
 * License, or (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU Affero General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License
22
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
 *
24
 */
25
26
/** global: OCA */
27
/** global: api */
28
/** global: search */
29
/** global: result */
30
/** global: settings */
31
32
33
34
var curr = {
35
	providerResult: [],
36
	page: 1,
37
	lastRequest: '',
38
	lastRequestTimer: null,
39
	lastRequestTimerQueued: false,
40
	lastRequestTimerForcing: false,
41
42
	setProviderResult: function (id, value) {
43
		curr.providerResult[id] = value;
44
	},
45
46
	getProviderResult: function (id) {
47
		var current = curr.providerResult[id];
48
		if (!current) {
49
			current = [];
50
		}
51
52
		return current;
53
	}
54
55
};
56
57
58
var nav = {
59
60
		failedToAjax: function () {
61
			// OCA.notification.onFail(
62
			// 	'Failed to connect to cloud, page will refresh within few seconds');
63
			// window.setTimeout(function () {
64
			// 	window.location.reload(true);
65
			// }, 4000);
66
		},
67
68
69
		manageDivProviderNavigation: function (divProviderNavigation, request, meta) {
70
71
			var maxPage = Math.ceil(meta.total / request.size);
72
73
			divProviderNavigation.attr('data-time', meta.time);
74
			divProviderNavigation.attr('data-page', request.page);
75
			divProviderNavigation.attr('data-options', JSON.stringify(request.options));
76
			divProviderNavigation.attr('data-search', request.search);
77
			divProviderNavigation.attr('data-max-page', maxPage);
78
			divProviderNavigation.attr('data-size', request.size);
79
			divProviderNavigation.attr('data-total', meta.total);
80
81
			var providerTitle = divProviderNavigation.attr('data-provider-title');
82
			var left = "Search " + providerTitle + " for '" + request.search + "' returned " +
83
				meta.total + " results in " + meta.time + "ms";
84
			divProviderNavigation.find('.provider_navigation_left').text(left);
85
86
			divProviderNavigation.find('.provider_navigation_curr').text(request.page + ' / ' +
87
				maxPage);
88
89
			divProviderNavigation.find('.provider_navigation_prev').stop().fadeTo(200,
90
				(request.page > 1) ? 1 : 0);
91
			divProviderNavigation.find('.provider_navigation_next').stop().fadeTo(200,
92
				(request.page < maxPage) ? 1 : 0);
93
		},
94
95
96
		manageDivProviderResult: function (divProviderResult, newResult, oldResult) {
97
			//replaceWith();
98
			nav.divProviderResultAddItems(divProviderResult, newResult, oldResult);
99
			if (oldResult) {
100
				nav.divProviderResultRemoveItems(divProviderResult, newResult, oldResult);
101
				nav.divProviderResultMoveItems(divProviderResult, newResult, oldResult);
102
			}
103
		},
104
105
106
		divProviderResultAddItems: function (divProviderResult, newResult, oldResult) {
107
108
			var precItem = null;
109
			for (var i = 0; i < newResult.length; i++) {
110
				var entry = newResult[i];
111
				if (result.getResultIndex(entry.id, oldResult) > -1) {
112
					precItem = nav.getDivResult(entry.id, divProviderResult);
113
					continue;
114
				}
115
116
				var divResult = nav.generateDivResult(entry, nav.generateTemplateEntry(entry));
117
				if (precItem === null) {
118
					divProviderResult.prepend(divResult);
119
				} else {
120
					precItem.after(divResult);
121
				}
122
123
				divResult.slideDown(settings.delay_result, function () {
0 ignored issues
show
Bug introduced by
It is generally not recommended to make functions within a loop.

While making functions in a loop will not lead to any runtime error, the code might not behave as you expect as the variables in the scope are not imported by value, but by reference. Let’s take a look at an example:

var funcs = [];
for (var i=0; i<10; i++) {
    funcs.push(function() {
        alert(i);
    });
}

funcs[0](); // alert(10);
funcs[1](); // alert(10);
/// ...
funcs[9](); // alert(10);

If you would instead like to bind the function inside the loop to the value of the variable during that specific iteration, you can create the function from another function:

var createFunc = function(i) {
    return function() {
        alert(i);
    };
};

var funcs = [];
for (var i=0; i<10; i++) {
    funcs.push(createFunc(i));
}

funcs[0](); // alert(0)
funcs[1](); // alert(1)
// ...
funcs[9](); // alert(9)
Loading history...
124
					$(this).children('.result_template').fadeTo(settings.delay_result, 1);
125
				});
126
127
				precItem = divResult;
128
			}
129
130
		},
131
132
133
		divProviderResultRemoveItems: function (divProviderResult, newResult, oldResult) {
134
			for (var i = 0; i < oldResult.length; i++) {
135
				var entry = oldResult[i];
136
				if (result.getResultIndex(entry.id, newResult) === -1) {
137
					var divResult = nav.getDivResult(entry.id, divProviderResult);
138
					divResult.fadeTo(settings.delay_result, 0, function () {
0 ignored issues
show
Bug introduced by
It is generally not recommended to make functions within a loop.

While making functions in a loop will not lead to any runtime error, the code might not behave as you expect as the variables in the scope are not imported by value, but by reference. Let’s take a look at an example:

var funcs = [];
for (var i=0; i<10; i++) {
    funcs.push(function() {
        alert(i);
    });
}

funcs[0](); // alert(10);
funcs[1](); // alert(10);
/// ...
funcs[9](); // alert(10);

If you would instead like to bind the function inside the loop to the value of the variable during that specific iteration, you can create the function from another function:

var createFunc = function(i) {
    return function() {
        alert(i);
    };
};

var funcs = [];
for (var i=0; i<10; i++) {
    funcs.push(createFunc(i));
}

funcs[0](); // alert(0)
funcs[1](); // alert(1)
// ...
funcs[9](); // alert(9)
Loading history...
139
						$(this).slideUp(settings.delay_result, function () {
140
							$(this).remove();
141
						});
142
					});
143
				}
144
			}
145
		},
146
147
148
		divProviderResultMoveItems: function (divProviderResult, newResult, oldResult) {
149
150
			var precId = '';
151
152
			oldResult = result.recalibrateResult(oldResult, newResult);
153
			newResult = result.recalibrateResult(newResult, oldResult);
154
			for (var i = 0; i < newResult.length; i++) {
155
				var entry = newResult[i];
156
157
				var pos = result.getResultIndex(entry.id, oldResult);
158
				if (pos > -1 && pos !== i) {
159
					nav.animateMoveDivResult(entry.id, divProviderResult, precId);
160
				}
161
162
				precId = newResult[i].id;
163
			}
164
		},
165
166
167
		animateMoveDivResult: function (entryId, divProviderResult, precId) {
168
169
			var divResult = nav.getDivResult(entryId, divProviderResult);
170
171
			if (precId === '') {
172
				divResult.fadeTo(settings.delay_result, 0.35, function () {
173
					$(this).prependTo(divProviderResult).fadeTo(100, 1);
174
				});
175
			} else {
176
				var precItem = nav.getDivResult(precId, divProviderResult);
177
				divResult.fadeTo(settings.delay_result, 0.35, function () {
178
					$(this).insertAfter(precItem).fadeTo(100, 1);
179
				});
180
			}
181
182
		},
183
184
185
		getDivProvider: function (providerId, providerName) {
186
			var ret = null;
187
			settings.resultContainer.children('.provider_header').each(function () {
188
				if ($(this).attr('data-id') === providerId) {
189
					ret = $(this);
190
				}
191
			});
192
193
			if (ret === null) {
194
				ret = nav.generateDivProvider(providerId, providerName);
195
				settings.resultContainer.append(ret);
196
			}
197
198
			return ret;
199
		},
200
201
202
		getDivResult: function (resultId, divProviderResult) {
203
			var ret = null;
204
			divProviderResult.children('.result_entry').each(function () {
205
				if ($(this).attr('data-id') === resultId) {
206
					ret = $(this);
207
				}
208
			});
209
210
			return ret;
211
		},
212
213
214
		fillDivResult: function (divResult, entry) {
215
			divResult.find('#title').text(entry.title);
216
			divResult.find('#score').text(entry.score);
217
218
			nav.fillDivResultExcepts(divResult, entry);
219
220
			if (entry.link !== '') {
221
				divResult.on('click', function () {
222
					window.open(entry.link, '_self');
223
				});
224
				divResult.find('div').each(function () {
225
					$(this).css('cursor', 'pointer');
226
				});
227
			}
228
		},
229
230
231
		/**
232
		 * @namespace entry.excerpts
233
		 */
234
		fillDivResultExcepts: function (divResult, entry) {
235
			if (entry.excerpts === null) {
236
				return;
237
			}
238
239
			if (entry.excerpts.length > 0) {
240
				divResult.find('#line1').text(entry.excerpts[0]);
241
			}
242
243
			if (entry.excerpts.length > 1) {
244
				divResult.find('#line2').text(entry.excerpts[1]);
245
			}
246
247
		},
248
249
		onEntryGenerated: function (divResult) {
250
251
			nav.deleteEmptyDiv(divResult, '#line1');
252
			nav.deleteEmptyDiv(divResult, '#line2');
253
254
			if (settings.parentHasMethod('onEntryGenerated')) {
255
				settings.parent.onEntryGenerated(divResult);
256
			}
257
		},
258
259
		onSearchRequest: function (data) {
260
			if (settings.parentHasMethod('onSearchRequest')) {
261
				settings.parent.onSearchRequest(data);
262
			}
263
		},
264
265
		onSearchReset: function () {
266
			if (settings.parentHasMethod('onSearchReset')) {
267
				settings.parent.onSearchReset();
268
			}
269
		},
270
271
		onResultDisplayed: function (data) {
272
			if (settings.parentHasMethod('onResultDisplayed')) {
273
				settings.parent.onResultDisplayed(data);
274
			}
275
		},
276
277
		onResultClose: function () {
278
			if (settings.parentHasMethod('onResultClose')) {
279
				settings.parent.onResultClose();
280
			}
281
		},
282
283
		onError: function (data) {
284
			if (settings.parentHasMethod('onError')) {
285
				settings.parent.onError(data);
286
			}
287
		},
288
289
		deleteEmptyDiv: function (entry, divId) {
290
			var div = entry.find(divId);
291
			if (div.text() === '') {
292
				div.remove();
293
			}
294
		},
295
296
297
		generateTemplateEntry: function (document) {
298
			var divTemplate = settings.entryTemplate;
299
			if (divTemplate === null) {
300
				divTemplate = settings.generateDefaultTemplate();
301
			}
302
303
			if (!divTemplate.length) {
304
				console.log('FullTextSearch Error: template_entry is not defined');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
305
				return;
306
			}
307
308
			var tmpl = divTemplate.html();
309
			tmpl = tmpl.replace(/%%id%%/g, escapeHTML(document.id));
310
311
			var div = $('<div>', {class: 'result_template'});
312
			div.html(tmpl).fadeTo(0);
313
314
			return div;
315
		},
316
317
318
		generateDivResult: function (entry, divResultContent) {
319
			var divResult = $('<div>', {class: 'result_entry'});
320
			divResult.hide();
321
			divResult.attr('data-id', entry.id);
322
			divResult.attr('data-link', entry.link);
323
			divResult.attr('data-result', JSON.stringify(entry));
324
			divResult.append(divResultContent);
325
326
			nav.fillDivResult(divResult, entry);
327
			nav.onEntryGenerated(divResult);
328
329
			return divResult;
330
		},
331
332
333
		generateDivProvider: function (providerId, providerName) {
334
335
336
			var divProviderNavigation = $('<div>', {class: 'provider_navigation'});
337
			divProviderNavigation.attr('data-provider-id', providerId);
338
			divProviderNavigation.attr('data-provider-title', providerName);
339
			divProviderNavigation.append($('<div>', {class: 'provider_navigation_left'}));
340
341
			var divProviderPagination = $('<div>', {class: 'provider_navigation_right'});
342
			var divProviderPaginationPrev = $('<div>', {class: 'icon-page-prev provider_navigation_prev'});
343
			divProviderPaginationPrev.on('click', function () {
344
				fullTextSearch.search({
0 ignored issues
show
Bug introduced by
The variable fullTextSearch seems to be never declared. If this is a global, consider adding a /** global: fullTextSearch */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
345
					providers: providerId,
346
					options: JSON.parse(divProviderNavigation.attr('data-options')),
347
					search: divProviderNavigation.attr('data-search'),
348
					page: Number(divProviderNavigation.attr('data-page')) - 1,
349
					size: divProviderNavigation.attr('data-size')
350
				});
351
			});
352
			divProviderPagination.append(divProviderPaginationPrev);
353
354
			divProviderPagination.append($('<div>', {class: 'provider_navigation_curr'}));
355
356
			var divProviderPaginationNext = $('<div>', {class: 'icon-page-next provider_navigation_next'});
357
			divProviderPaginationNext.on('click', function () {
358
				fullTextSearch.search({
0 ignored issues
show
Bug introduced by
The variable fullTextSearch seems to be never declared. If this is a global, consider adding a /** global: fullTextSearch */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
359
					providers: providerId,
360
					options: JSON.parse(divProviderNavigation.attr('data-options')),
361
					search: divProviderNavigation.attr('data-search'),
362
					page: Number(divProviderNavigation.attr('data-page')) + 1,
363
					size: divProviderNavigation.attr('data-size')
364
				});
365
			});
366
			divProviderPagination.append(divProviderPaginationNext);
367
368
			if (settings.searchProviderId !== '') {
369
				var divProviderPaginationClose = $('<div>',
370
					{class: 'icon-close provider_navigation_close'});
371
				divProviderPaginationClose.on('click', function () {
372
					nav.onResultClose();
373
				});
374
				divProviderPagination.append(divProviderPaginationClose);
375
			}
376
377
378
			divProviderNavigation.append(divProviderPagination);
379
380
			var divProviderResult = $('<div>', {class: 'provider_result'});
381
382
			var divProvider = $('<div>', {class: 'provider_header'});
383
			divProvider.hide();
384
			divProvider.attr('data-id', providerId);
385
			divProvider.append(divProviderNavigation);
386
			divProvider.append(divProviderResult);
387
388
			return divProvider;
389
		}
390
391
	}
392
;
393